home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / comm2 / kms20src.lha / KMSUM / kmsum.c < prev    next >
C/C++ Source or Header  |  1995-09-24  |  60KB  |  2,058 lines

  1. /*************************************************************************
  2.  *
  3.  *   Copyright (C) 1995 Thomas Schwarz
  4.  *                      <kmshq@ruatha.muc.de>
  5.  *                      <Schwarz.Thomas@fhm.de>
  6.  *
  7.  *   This program is free software; you can redistribute it and/or modify
  8.  *   it under the terms of the GNU General Public License as published by
  9.  *   the Free Software Foundation; either version 2 of the License, or
  10.  *   any later version.
  11.  *
  12.  *   This program is distributed in the hope that it will be useful,
  13.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *   GNU General Public License for more details.
  16.  *
  17.  *   You should have received a copy of the GNU General Public License
  18.  *   along with this program; if not, write to the Free Software
  19.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  *
  21.  *************************************************************************/
  22.  
  23. #include "KMSUM.h"
  24. #include <KMS/KMS_def.h>
  25.  
  26. /* Defines */
  27.  
  28. #define VERSION "1.23"
  29.  
  30. #define MID_ADD     1
  31. #define MID_REMOVE  2
  32. #define MID_UP      3
  33. #define MID_DOWN    4
  34. #define MID_SORT    5
  35. #define MID_EDIT    6
  36. #define MID_OK      7
  37. #define MID_ABOUT   8
  38. #define MID_SELUSER 9
  39.  
  40. #define EID_USE     20
  41. #define EID_CANCEL  21
  42. #define EID_SELAB   22
  43. #define EID_NAMEAB  23
  44.  
  45. /* Escape Sequences */
  46.  
  47. #define eR "\033r"
  48. #define eC "\033c"
  49. #define eL "\033l"
  50.  
  51. #define eN "\033n"
  52. #define eB "\033b"
  53. #define eI "\033i"
  54.  
  55. #define ePB "\0332"
  56. #define ePW "\0338"
  57.  
  58. /* Prototypes */
  59.  
  60. int main(int, char **);
  61. BOOL InitUAF(VOID);
  62. BOOL ReadUserList(VOID);
  63. BOOL WriteUserList(VOID);
  64. struct UserNode *AddUN(VOID);
  65. VOID DeleteUN(struct UserNode *);
  66. struct UserNode *UserCheck(STRPTR);
  67. BOOL ParseArgs(VOID);
  68. VOID Sense(APTR, STRPTR);
  69. VOID ReadAccBits(VOID);
  70. BOOL WriteAccBits(VOID);
  71. BOOL MakeChanges(VOID);
  72. struct KMSBase *GetKMSBase(VOID);
  73. VOID Error(STRPTR);
  74. VOID ConvertSpace(STRPTR);
  75. VOID TakeUSem(BOOL);
  76. VOID DropUSem(VOID);
  77. VOID TakeMSem(BOOL);
  78. VOID DropMSem(VOID);
  79. BOOL AddUMSUser(struct UserNode *unode);
  80. BOOL DelUMSUser(struct UserNode *unode);
  81.  
  82. /* Hooks */
  83.  
  84. SAVEDS ASM LONG list_dspfunc(
  85.    REG(a0) struct Hook *hook,
  86.    REG(a2) char **array,
  87.    REG(a1) struct UserNode *user)
  88.    {
  89.    if(user)
  90.       *array = user->UserData.Name;
  91.    else
  92.       *array = NULL;
  93.    return 0;
  94.    }
  95.  
  96. static struct Hook list_dsphook = {
  97.    {NULL, NULL},
  98.    (VOID *)list_dspfunc,
  99.    NULL, NULL
  100.    };
  101.  
  102. SAVEDS ASM LONG list_cmpfunc(
  103.    REG(a0) struct Hook *hook,
  104.    REG(a1) struct UserNode *user1,
  105.    REG(a2) struct UserNode *user2)
  106.    {
  107.    if(user1 && user2)
  108.       return stricmp(user1->UserData.Name, user2->UserData.Name);
  109.    else
  110.       return 0;
  111.    }
  112.  
  113. static struct Hook list_cmphook = 
  114.    {
  115.    {NULL, NULL},
  116.    (VOID *)list_cmpfunc,
  117.    NULL, NULL
  118.    };
  119.  
  120. /* Vars */
  121.  
  122. static Object *App       ; /* Application object        */
  123. static Object *WI_Manager; /* Main Window object        */
  124. static Object *WI_Editor ; /* Editor Window object      */
  125. static Object *LV_Users  ; /* Users Listview object     */
  126. static Object *LV_AccBits; /* AccBits Listview object   */
  127. static Object *BT_Add    ; /* Add Button object         */
  128. static Object *BT_Remove ; /* Remove Button object      */
  129. static Object *BT_Up     ; /* Up Button object          */
  130. static Object *BT_Down   ; /* Down Button object        */
  131. static Object *BT_Sort   ; /* Sort Button object        */
  132. static Object *BT_Edit   ; /* Edit Button object        */
  133. static Object *BT_EUse   ; /* Edit-Use Button object    */
  134. static Object *BT_ECancel; /* Edit-Cancel Button object */
  135.  
  136. /* String-Gadget objects */
  137.  
  138. static Object *ST_Name;
  139. static Object *ST_Password;
  140. static Object *ST_RealName;
  141. static Object *ST_Street;
  142. static Object *ST_City;
  143. static Object *ST_Phone;
  144. static Object *ST_Prompt;
  145. static Object *ST_AccBit;
  146. static Object *ST_Quota;
  147.  
  148. /* Slider objects */
  149.  
  150. static Object *SL_Level;
  151. static Object *SL_PageLen;
  152. static Object *SL_LineLen;
  153.  
  154. /* Cycle objects */
  155.  
  156. static Object *CY_CharSet;
  157. static Object *CY_ReadMode;
  158. static Object *CY_Terminal;
  159. static Object *CY_Editor;
  160.  
  161. /* CheckMark objects */
  162.  
  163. static Object *CH_MsgHead;
  164. static Object *CH_AutoList;
  165. static Object *CH_AutoAreaList;
  166. static Object *CH_Input;
  167. static Object *CH_WriteAcc;
  168. static Object *CH_ClearScreen;
  169.  
  170. static const char *CYA_CharSets[] =
  171.    {
  172.    "0",
  173.    "1",
  174.    "2",
  175.    "3",
  176.    "4",
  177.    "5",
  178.    "6",
  179.    "7",
  180.    "8",
  181.    "9",
  182.    NULL
  183.    };
  184.  
  185. static const char *CYA_ReadModes[] =
  186.    {
  187.    "Next",
  188.    "Next new",
  189.    "Next selected",
  190.    "Next Reply",
  191.    NULL
  192.    };
  193.  
  194. static const char *CYA_Terminal[] =
  195.    {
  196.    "TTY",
  197.    "ANSI",
  198.    NULL
  199.    };
  200.  
  201. static const char *CYA_Editor[] =
  202.    {
  203.    "Line oriented",
  204.    "Full Screen",
  205.    NULL
  206.    };
  207.  
  208. /* Menü */
  209.  
  210. static const struct NewMenu MenuList[] =
  211.    {
  212.    {NM_TITLE, "Project",   0,   0,  0, 0},
  213.    {NM_ITEM,  "About...",  "?", 0,  0, (APTR)MID_ABOUT},
  214.    {NM_ITEM,  NM_BARLABEL, 0,   0,  0, 0},
  215.    {NM_ITEM,  "Quit",      "Q", 0,  0, (APTR)MID_OK},
  216.    {NM_END,   NULL,        0,   0,  0, 0}
  217.    };
  218.  
  219. /* Misc */
  220.  
  221. STRPTR Username = NULL;
  222. ULONG UserListNum = 0;
  223. struct Library *UMSBase = NULL;
  224. UMSAccount SysUMSAccount = NULL;
  225.  
  226. ULONG SystemStartups;
  227. TEXT AccBitNames[32][LEN_ACCBITNAME+1];
  228.  
  229. FILE *Changes;
  230. TEXT ChangesFile[16];
  231.  
  232. struct KMSBase *KMSBase = NULL;
  233.  
  234. /* Hauptprogramm */
  235.  
  236. /// "main"
  237.  
  238. int main(int argc, char *argv[])
  239.    {
  240.    struct UserNode *un;
  241.    struct Userdaten user;
  242.    BOOL running = TRUE, addflag = FALSE;
  243.    BOOL userschanged = FALSE, bitschanged = FALSE;
  244.    ULONG signal, acc;
  245.    LONG num, entries, state;
  246.    TEXT password[LEN_PASSWORD+1];
  247.  
  248.    sprintf(ChangesFile, "T:%08x.tmp", time(NULL));
  249.  
  250.    App = NULL;
  251.  
  252.    init();
  253.  
  254.    if(!ParseArgs())
  255.       Sense(App, NULL);
  256.  
  257.    if(!GetKMSBase())
  258.       Sense(App, NULL);
  259.  
  260.    App = ApplicationObject,
  261.       MUIA_Application_Title      , "KMS User Manager",
  262.       MUIA_Application_Version    , "$VER: KMSUM " VERSION " (" __COMMODORE_DATE__ ")",
  263.       MUIA_Application_Copyright  , "©1994 Thomas Schwarz",
  264.       MUIA_Application_Author     , "Thomas Schwarz",
  265.       MUIA_Application_Description, "Manages Karfunkel Mailbox System Users.",
  266.       MUIA_Application_Base       , "KMSUM",
  267.       MUIA_Application_Menu       , MenuList,
  268.       MUIA_Application_SingleTask, TRUE,
  269.       SubWindow, WI_Manager = WindowObject,
  270.          MUIA_Window_ID, MAKE_ID('M','A','I','N'),
  271.          MUIA_Window_Title, "KMS User Manager",
  272.          WindowContents, VGroup,
  273.             Child, HGroup,
  274.                Child, VGroup,
  275.                   GroupFrameT("Users"),
  276.                   Child, LV_Users = ListviewObject,
  277.                      MUIA_Listview_List, ListObject,
  278.                         InputListFrame,
  279.                         MUIA_List_DisplayHook, &list_dsphook,
  280.                         MUIA_List_CompareHook, &list_cmphook,
  281.                         End,
  282.                      End,
  283.                   End,
  284.                Child, VGroup,
  285.                   GroupFrameT("Menu"),
  286.                   MUIA_Weight, 25,
  287.                   MUIA_Group_SameSize, TRUE,
  288.                   Child, BT_Add    = KeyButton("Add"   , 'a'),
  289.                   Child, BT_Remove = KeyButton("Remove", 'r'),
  290.                   Child, BT_Up     = KeyButton("Up"    , 'u'),
  291.                   Child, BT_Down   = KeyButton("Down"  , 'd'),
  292.                   Child, BT_Sort   = KeyButton("Sort"  , 'o'),
  293.                   Child, BT_Edit   = KeyButton("Edit"  , 'e'),
  294.                   End,
  295.                End,
  296.             End,
  297.          End,
  298.       SubWindow, WI_Editor = WindowObject,
  299.          MUIA_Window_ID, MAKE_ID('E','D','I','T'),
  300.          MUIA_Window_Title, "KMS User Editor",
  301.          WindowContents, VGroup,
  302.             Child, HGroup,
  303.                Child, ColGroup(2),
  304.                   Child, KeyLabel2("Username:", 'u'),
  305.                   Child, ST_Name = StringObject,
  306.                      StringFrame,
  307.                      MUIA_String_MaxLen, LEN_USERNAME+1,
  308.                      MUIA_ControlChar, 'u',
  309.                      End,
  310.                   Child, KeyLabel2("Realname:", 'e'),
  311.                   Child, ST_RealName = StringObject,
  312.                      StringFrame,
  313.                      MUIA_String_MaxLen, LEN_REALNAME+1,
  314.                      MUIA_ControlChar, 'e',
  315.                      End,
  316.                   Child, KeyLabel2("Street:", 't'),
  317.                   Child, ST_Street = StringObject,
  318.                      StringFrame,
  319.                      MUIA_String_MaxLen, LEN_STREET+1,
  320.                      MUIA_ControlChar, 't',
  321.                      End,
  322.                   Child, KeyLabel2("City:", 'y'),
  323.                   Child, ST_City = StringObject,
  324.                      StringFrame,
  325.                      MUIA_String_MaxLen, LEN_CITY+1,
  326.                      MUIA_ControlChar, 'y',
  327.                      End,
  328.                   Child, KeyLabel2("Phone:", 'p'),
  329.                   Child, ST_Phone = StringObject,
  330.                      StringFrame,
  331.                      MUIA_String_MaxLen, LEN_PHONE+1,
  332.                      MUIA_ControlChar, 'p',
  333.                      End,
  334.                   Child, KeyLabel2("New Pwd:", 'w'),
  335.                   Child, ST_Password = StringObject,
  336.                      StringFrame,
  337.                      MUIA_String_Secret, TRUE,
  338.                      MUIA_String_MaxLen, LEN_PASSWORD+1,
  339.                      MUIA_ControlChar, 'w',
  340.                      End,
  341.                   Child, KeyLabel2("Prompt:", 'r'),
  342.                   Child, ST_Prompt = StringObject,
  343.                      StringFrame,
  344.                      MUIA_String_MaxLen, LEN_UPROMPT+1,
  345.                      MUIA_ControlChar, 'r',
  346.                      End,
  347.                   End,
  348.                Child, HSpace(10),
  349.                Child, VGroup,
  350.                   MUIA_Weight, 25,
  351.                   Child, ColGroup(2),
  352.                      Child, Label2("Level:"),
  353.                      Child, SL_Level = SliderObject,
  354.                         MUIA_Group_Horiz , TRUE,
  355.                         MUIA_Slider_Min  , 0,
  356.                         MUIA_Slider_Max  , 255,
  357.                         MUIA_Slider_Level, 0,
  358.                         End,
  359.                      End,
  360.                   Child, VGroup,
  361.                      GroupFrameT("AccessBits"),
  362.                      Child, LV_AccBits = ListviewObject,
  363.                         MUIA_Listview_MultiSelect, TRUE,
  364.                         MUIA_Listview_List, ListObject,
  365.                            InputListFrame,
  366.                            End,
  367.                         End,
  368.                      Child, ST_AccBit = StringObject,
  369.                         StringFrame,
  370.                         MUIA_String_Reject, " ",
  371.                         MUIA_String_MaxLen, LEN_ACCBITNAME+1,
  372.                         MUIA_String_AttachedList, LV_AccBits,
  373.                         End,
  374.                      End,
  375.                   End,
  376.                End,
  377.             Child, VSpace(0),
  378.             Child, HGroup,
  379.                Child, Label2("Chars/Line:"),
  380.                Child, SL_LineLen = SliderObject,
  381.                   MUIA_Group_Horiz , TRUE,
  382.                   MUIA_Slider_Min  , 40,
  383.                   MUIA_Slider_Max  , 255,
  384.                   MUIA_Slider_Level, 80,
  385.                   End,
  386.                Child, HSpace(0),
  387.                Child, Label2("Lines/Page:"),
  388.                Child, SL_PageLen = SliderObject,
  389.                   MUIA_Group_Horiz , TRUE,
  390.                   MUIA_Slider_Min  , 10,
  391.                   MUIA_Slider_Max  , 255,
  392.                   MUIA_Slider_Level, 25,
  393.                   End,
  394.                Child, HSpace(0),
  395.                Child, Label2("Quota:"),
  396.                Child, ST_Quota = StringObject,
  397.                   StringFrame,
  398.                   MUIA_String_MaxLen, 5,
  399.                   MUIA_String_Accept, "0123456789",
  400.                   MUIA_String_Integer, 5,
  401.                   End,
  402.                End,
  403.             Child, VSpace(0),
  404.             Child, HGroup,
  405.                Child, ColGroup(2),
  406.                   Child, Label1("Terminal:"),
  407.                   Child, CY_Terminal = CycleObject,
  408.                      MUIA_Cycle_Entries, CYA_Terminal,
  409.                      End,
  410.                   Child, Label1("Char.Set:" ),
  411.                   Child, CY_CharSet = CycleObject,
  412.                      MUIA_Cycle_Entries, CYA_CharSets,
  413.                      End,
  414.                   Child, Label1("Editor:"),
  415.                   Child, CY_Editor = CycleObject,
  416.                      MUIA_Cycle_Entries, CYA_Editor,
  417.                      End,
  418.                   Child, Label1("Read Mode:" ),
  419.                   Child, CY_ReadMode = CycleObject,
  420.                      MUIA_Cycle_Entries, CYA_ReadModes,
  421.                      End,
  422.                   End,
  423.                Child, HSpace(0),
  424.                Child, ColGroup(2),
  425.                   Child, Label1("Auto-Msglist:"),
  426.                   Child, CH_AutoList = CheckMark(TRUE),
  427.                   Child, Label1("Auto-Arealist:"),
  428.                   Child, CH_AutoAreaList = CheckMark(TRUE),
  429.                   Child, Label1("Ext. Write Opt.:"),
  430.                   Child, CH_WriteAcc = CheckMark(TRUE),
  431.                   Child, Label1("Long Msg-Header:"),
  432.                   Child, CH_MsgHead = CheckMark(TRUE),
  433.                   Child, Label1("Insert Mode:"),
  434.                   Child, CH_Input = CheckMark(TRUE),
  435.                   Child, Label1("Clear Screen:"),
  436.                   Child, CH_ClearScreen = CheckMark(TRUE),
  437.                   End,
  438.                End,
  439.             Child, VSpace(0),
  440.             Child, HGroup,
  441.                MUIA_Group_SameSize, TRUE,
  442.                Child, BT_EUse    = KeyButton("Ok"    , 'o'),
  443.                Child, HSpace(0),
  444.                Child, BT_ECancel = KeyButton("Cancel", 'c'),
  445.                End,
  446.             End,
  447.          End,
  448.       End;
  449.  
  450.    if(!App)
  451.       Sense(App, "Failed to create application.");
  452.  
  453.    DoMethod(WI_Manager, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, App, 2, MUIM_Application_ReturnID, MID_OK);
  454.    DoMethod(LV_Users  , MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, App, 2, MUIM_Application_ReturnID, MID_EDIT);
  455.    DoMethod(LV_Users  , MUIM_Notify, MUIA_List_Active, MUIV_EveryTime, App, 2, MUIM_Application_ReturnID, MID_SELUSER);
  456.    DoMethod(BT_Up     , MUIM_Notify, MUIA_Pressed, FALSE, App, 2, MUIM_Application_ReturnID, MID_UP);
  457.    DoMethod(BT_Down   , MUIM_Notify, MUIA_Pressed, FALSE, App, 2, MUIM_Application_ReturnID, MID_DOWN);
  458.    DoMethod(BT_Add    , MUIM_Notify, MUIA_Pressed, FALSE, App, 2, MUIM_Application_ReturnID, MID_ADD);
  459.    DoMethod(BT_Remove , MUIM_Notify, MUIA_Pressed, FALSE, App, 2, MUIM_Application_ReturnID, MID_REMOVE);
  460.    DoMethod(BT_Sort   , MUIM_Notify, MUIA_Pressed, FALSE, App, 2, MUIM_Application_ReturnID, MID_SORT);
  461.    DoMethod(BT_Edit   , MUIM_Notify, MUIA_Pressed, FALSE, App, 2, MUIM_Application_ReturnID, MID_EDIT);
  462.  
  463.    DoMethod(WI_Manager, MUIM_Window_SetCycleChain, LV_Users, BT_Add,
  464.             BT_Remove, BT_Up, BT_Down, BT_Sort, BT_Edit, NULL);
  465.  
  466.    set(WI_Manager, MUIA_Window_DefaultObject, LV_Users);
  467.  
  468.    DoMethod(WI_Editor , MUIM_Notify, MUIA_Window_CloseRequest, TRUE, App, 2, MUIM_Application_ReturnID, EID_CANCEL);
  469.    DoMethod(BT_EUse   , MUIM_Notify, MUIA_Pressed, FALSE, App, 2, MUIM_Application_ReturnID, EID_USE);
  470.    DoMethod(BT_ECancel, MUIM_Notify, MUIA_Pressed, FALSE, App, 2, MUIM_Application_ReturnID, EID_CANCEL);
  471.    DoMethod(LV_AccBits, MUIM_Notify, MUIA_List_Active, MUIV_EveryTime, App, 2, MUIM_Application_ReturnID, EID_SELAB);
  472.    DoMethod(ST_AccBit , MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, App, 2, MUIM_Application_ReturnID, EID_NAMEAB);
  473.  
  474.    DoMethod(WI_Editor, MUIM_Window_SetCycleChain,
  475.             ST_Name, ST_RealName, ST_Street, ST_City, ST_Phone, ST_Password,
  476.             ST_Prompt, SL_Level, LV_AccBits, ST_AccBit, SL_LineLen, SL_PageLen,
  477.             ST_Quota, CY_Terminal, CY_CharSet, CY_Editor, CY_ReadMode, CH_AutoList, CH_AutoAreaList,
  478.             CH_WriteAcc, CH_MsgHead, CH_Input, CH_ClearScreen, BT_EUse, BT_ECancel, NULL);
  479.  
  480.    set(WI_Editor, MUIA_Window_DefaultObject, LV_AccBits);
  481.  
  482.    TakeUSem(FALSE);
  483.    
  484.    num = 0;
  485.    un = (struct UserNode *)KMSBase->UserList.mlh_Head;
  486.    while(un->Node.mln_Succ)
  487.       {
  488.       num++;
  489.  
  490.       if(Username && !stricmp(Username, un->UserData.Name))
  491.          UserListNum = num;
  492.  
  493.       DoMethod(LV_Users, MUIM_List_Insert, &un, 1, MUIV_List_Insert_Bottom);
  494.  
  495.       un = un->Node.mln_Succ;
  496.       }
  497.  
  498.    DropUSem();
  499.  
  500.    STRPTR entry;
  501.    UBYTE n;
  502.    for(n = 0; n < 32; n++)
  503.       {
  504.       entry = AccBitNames[n];
  505.       DoMethod(LV_AccBits, MUIM_List_Insert, &entry, 1, MUIV_List_Insert_Bottom);
  506.       }
  507.  
  508.    if(Username)
  509.       {
  510.       if(!UserListNum)
  511.          if(!MUI_RequestA(App, NULL, 0, "KMSUM Error", "Create|Abort", "No such user!", NULL))
  512.             Sense(App, NULL);
  513.  
  514.       if(UserListNum)
  515.          {
  516.          set(LV_Users, MUIA_List_Active, UserListNum-1);
  517.          DoMethod(App, MUIM_Application_ReturnID, MID_EDIT);
  518.          }
  519.       else
  520.          DoMethod(App, MUIM_Application_ReturnID, MID_ADD);
  521.       }
  522.    else
  523.       {
  524.       ULONG open;
  525.       set(WI_Manager, MUIA_Window_Open, TRUE);
  526.       get(WI_Manager, MUIA_Window_Open, &open);
  527.       if(!open)
  528.          Sense(App, "Failed to open window.");
  529.    
  530.       DoMethod(WI_Manager, MUIM_Window_ScreenToFront,);
  531.       }
  532.  
  533.    while(running)
  534.       {
  535.       switch(DoMethod(App, MUIM_Application_Input, &signal))
  536.          {
  537.          case MID_ABOUT:
  538.             MUI_RequestA(App, NULL, 0, "Information", "Ok",
  539.                          eC ePW "KMS User Manager\n\n"
  540.                          ePB "Version " VERSION " (" __COMMODORE_DATE__ ")\n"
  541.                          "Copyright 1994 by Thomas Schwarz.\n"
  542.                          "\nThis is a MUI-Application.\n"
  543.                          "MUI is copyrighted by Stefan Stuntz.", NULL);
  544.  
  545.             break;
  546.  
  547.          case MID_UP:
  548.             get(LV_Users, MUIA_List_Active, &num);
  549.             if(num != MUIV_List_Active_Off && num > 0)
  550.                {
  551.                DoMethod(LV_Users, MUIM_List_Exchange, num, num-1);
  552.                set(LV_Users, MUIA_List_Active, MUIV_List_Active_Up);
  553.  
  554.                userschanged = TRUE;
  555.                }
  556.             else
  557.                DisplayBeep(0);
  558.             
  559.             break;
  560.  
  561.          case MID_DOWN:
  562.             get(LV_Users, MUIA_List_Entries, &entries);
  563.             get(LV_Users, MUIA_List_Active, &num);
  564.             if(num != MUIV_List_Active_Off && num < entries-1)
  565.                {
  566.                DoMethod(LV_Users, MUIM_List_Exchange, num, num+1);
  567.                set(LV_Users, MUIA_List_Active, MUIV_List_Active_Down);
  568.  
  569.                userschanged = TRUE;
  570.                }
  571.             else
  572.                DisplayBeep(0);
  573.             
  574.             break;
  575.  
  576.          case MID_ADD:
  577.             un = AddUN();
  578.             if(un)
  579.                {
  580.                struct UserNode *defuser;
  581.  
  582.                addflag = TRUE;
  583.  
  584.                defuser = UserCheck("Default");
  585.                if (defuser)
  586.                   un->UserData = defuser->UserData;
  587.                else
  588.                   {
  589.                   un->UserData.Level = 10;
  590.                   un->UserData.Flags = UF_EMU_ANSI|UF_EDIT_INSERT|UF_RMODE_NEW|UF_SCREEN_ED|UF_AUTO_LIST|UF_AUTO_AREALIST;
  591.                   strcpy(un->UserData.Prompt, "[%p]> ");
  592.                   un->UserData.PageLen = 25;
  593.                   un->UserData.LineLen = 80;
  594.                   un->UserData.Quota = 10;
  595.                   }
  596.                *un->UserData.Name = '\0';
  597.                *un->UserData.RealName = '\0';
  598.  
  599.                if (Username)
  600.                   strcpy(un->UserData.Name, Username);
  601.  
  602.                DoMethod(App, MUIM_Application_ReturnID, MID_EDIT);
  603.                }
  604.             else
  605.                {
  606.                MUI_RequestA(App, NULL, 0, "KMSUM Error", "I see", "Couldn't create new user!", NULL);
  607.                if(Username)
  608.                   DoMethod(App, MUIM_Application_ReturnID, MID_OK);
  609.                }
  610.  
  611.             break;
  612.  
  613.          case MID_REMOVE:
  614.             DoMethod(LV_Users, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &un);
  615.             if(un)
  616.                {
  617.                if (MUI_RequestA(App, NULL, 0, "KMSUM Request", "Just do it!|No way!", "Do you really want to delete this user?", NULL))
  618.                   {
  619.                   DoMethod(LV_Users, MUIM_List_Remove, MUIV_List_Remove_Active);
  620.  
  621.                   /* UMS-User löschen */
  622.  
  623.                   DelUMSUser(un);
  624.  
  625.                   /* User-Directory löschen */
  626.  
  627.                   TEXT buffer[LEN_DOSPATH+1];
  628.                   strcpy(buffer, KMSBase->UserDir);
  629.                   strcat(buffer, un->UserData.Name);
  630.                   ConvertSpace(buffer);
  631.  
  632.                   Changes = fopen(ChangesFile, "a");
  633.                   if(Changes)
  634.                      {
  635.                      fprintf(Changes, "Delete >NIL: \"%s/#?\"\n", buffer);
  636.                      fprintf(Changes, "Delete >NIL: \"%s\"\n", buffer);
  637.                      fclose(Changes);
  638.                      }
  639.  
  640.                   DeleteUN(un);
  641.  
  642.                   userschanged = TRUE;
  643.                   }
  644.                }
  645.             else
  646.                DisplayBeep(0);
  647.             
  648.             break;
  649.  
  650.          case MID_SORT:
  651.             DoMethod(LV_Users, MUIM_List_Sort,);
  652.             userschanged = TRUE;
  653.             
  654.             break;
  655.  
  656.          case MID_EDIT:
  657.             if(!addflag)
  658.                DoMethod(LV_Users, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &un);
  659.  
  660.             if(un)
  661.                {
  662.                user = un->UserData;
  663.             
  664.                set(ST_Name, MUIA_String_Contents, user.Name);
  665.                set(ST_Password, MUIA_String_Contents, "");
  666.                set(SL_Level, MUIA_Slider_Level, (ULONG)user.Level);
  667.                set(ST_RealName, MUIA_String_Contents, user.RealName);
  668.                set(ST_Street, MUIA_String_Contents, user.Street);
  669.                set(ST_City, MUIA_String_Contents, user.City);
  670.                set(ST_Phone, MUIA_String_Contents, user.Phone);
  671.                set(ST_Prompt, MUIA_String_Contents, user.Prompt);
  672.                set(SL_PageLen, MUIA_Slider_Level, (ULONG)user.PageLen);
  673.                set(SL_LineLen, MUIA_Slider_Level, (ULONG)user.LineLen);
  674.                set(ST_Quota, MUIA_String_Integer, user.Quota);
  675.  
  676.                for(num = 0; num < 32; num++)
  677.                   DoMethod(LV_AccBits, MUIM_List_Select, num, MUIV_List_Select_Off, NULL);
  678.  
  679.                num = 0;
  680.                acc = user.AccessBits;
  681.                while(acc)
  682.                   {
  683.                   if(acc & 1)
  684.                      DoMethod(LV_AccBits, MUIM_List_Select, num, MUIV_List_Select_On, NULL);
  685.  
  686.                   acc = acc / 2;
  687.                   num++;
  688.                   }
  689.  
  690.                num = 0;
  691.                if(user.Flags & UF_RMODE_NEW)
  692.                   num = 1;
  693.                else if(user.Flags & UF_RMODE_SEL)
  694.                   num = 2;
  695.                else if(user.Flags & UF_RMODE_THRD)
  696.                   num = 3;
  697.                set(CY_ReadMode, MUIA_Cycle_Active, num);
  698.                set(CY_CharSet, MUIA_Cycle_Active, user.CharSet);
  699.                set(CY_Terminal, MUIA_Cycle_Active, (user.Flags & UF_EMU_ANSI) ? 1 : 0);
  700.                set(CY_Editor, MUIA_Cycle_Active, (user.Flags & UF_SCREEN_ED) ? 1 : 0);
  701.  
  702.                set(CH_AutoList, MUIA_Selected, (user.Flags & UF_AUTO_LIST) ? TRUE : FALSE);
  703.                set(CH_AutoAreaList, MUIA_Selected, (user.Flags & UF_AUTO_AREALIST) ? TRUE : FALSE);
  704.                set(CH_WriteAcc, MUIA_Selected, (user.Flags & UF_EXTSEND) ? TRUE : FALSE);
  705.                set(CH_MsgHead, MUIA_Selected, (user.Flags & UF_HEAD_LONG) ? TRUE : FALSE);
  706.                set(CH_Input, MUIA_Selected, (user.Flags & UF_EDIT_INSERT) ? TRUE : FALSE);
  707.                set(CH_ClearScreen, MUIA_Selected, (user.Flags & UF_CLS) ? TRUE : FALSE);
  708.  
  709.                ULONG edopen;
  710.                set(WI_Editor, MUIA_Window_Open, TRUE);
  711.                get(WI_Editor, MUIA_Window_Open, &edopen);
  712.                if(!edopen)
  713.                   {
  714.                   MUI_RequestA(App, NULL, 0, "KMSUM Error", "I see", "Couldn't open window!", NULL);
  715.                   if(addflag)
  716.                      DeleteUN(un);
  717.                   addflag = FALSE;
  718.                   if(Username)
  719.                      DoMethod(App, MUIM_Application_ReturnID, MID_OK);
  720.                   }
  721.                else
  722.                   set(WI_Manager, MUIA_Window_Sleep, TRUE);
  723.  
  724.                DoMethod(WI_Editor, MUIM_Window_ScreenToFront,);
  725.                }
  726.             else
  727.                {
  728.                DisplayBeep(0);
  729.                if(Username)
  730.                   DoMethod(App, MUIM_Application_ReturnID, MID_OK);
  731.                }
  732.  
  733.             break;
  734.  
  735.          case MID_OK:
  736.          case MUIV_Application_ReturnID_Quit:
  737.             if(addflag)
  738.                DeleteUN(un);
  739.             addflag = FALSE;
  740.  
  741.             /* Liste sichern */
  742.  
  743.             if(!Username || !FindPort("KMS"))
  744.                {
  745.                set(App, MUIA_Application_Sleep, TRUE);
  746.                if(userschanged && !WriteUserList())
  747.                   MUI_RequestA(App, NULL, 0, "KMSUM Error", "I see", "Saving userlist failed!", NULL);
  748.                if(bitschanged && !WriteAccBits())
  749.                   MUI_RequestA(App, NULL, 0, "KMSUM Error", "I see", "Saving access bits failed!", NULL);
  750.                set(App, MUIA_Application_Sleep, FALSE);
  751.                }
  752.             else if(userschanged)
  753.                KMSBase->Modified |= MODIFIED_USERS;
  754.  
  755.             if(!MakeChanges())
  756.                MUI_RequestA(App, NULL, 0, "KMSUM Error", "I see", "Executing DOS changes failed!", NULL);
  757.  
  758.             running = FALSE;
  759.  
  760.             break;
  761.  
  762.          case MID_SELUSER:
  763.             set(WI_Manager, MUIA_Window_ActiveObject, LV_Users);
  764.  
  765.             break;
  766.  
  767.          case EID_SELAB:
  768.             set(WI_Editor, MUIA_Window_ActiveObject, LV_AccBits);
  769.             get(LV_AccBits, MUIA_List_Active, &num);
  770.             set(ST_AccBit, MUIA_String_Contents, AccBitNames[num]);
  771.  
  772.             break;
  773.  
  774.          case EID_NAMEAB:
  775.             STRPTR text;
  776.             get(LV_AccBits, MUIA_List_Active, &num);
  777.             get(ST_AccBit, MUIA_String_Contents, &text);
  778.             strcpy(AccBitNames[num], text);
  779.             DoMethod(LV_AccBits, MUIM_List_Redraw, MUIV_List_Redraw_Active);
  780.             
  781.             bitschanged = TRUE;
  782.  
  783.             break;
  784.  
  785.          case EID_USE:
  786.             STRPTR text;
  787.             ULONG value;
  788.             TEXT userdir[LEN_DOSPATH+1];
  789.  
  790.             strcpy(userdir, KMSBase->UserDir);
  791.  
  792.             get(ST_Name, MUIA_String_Contents, &text);
  793.             strcpy(user.Name, text);
  794.             ConvertSpace(user.Name);
  795.             get(ST_Password, MUIA_String_Contents, &text);
  796.             strcpy(password, text);
  797.             get(SL_Level, MUIA_Slider_Level, &value);
  798.             user.Level = (UWORD)value;
  799.             get(ST_RealName, MUIA_String_Contents, &text);
  800.             strcpy(user.RealName, text);
  801.             get(ST_Street, MUIA_String_Contents, &text);
  802.             strcpy(user.Street, text);
  803.             get(ST_City, MUIA_String_Contents, &text);
  804.             strcpy(user.City, text);
  805.             get(ST_Phone, MUIA_String_Contents, &text);
  806.             strcpy(user.Phone, text);
  807.             get(ST_Prompt, MUIA_String_Contents, &text);
  808.             strcpy(user.Prompt, text);
  809.             get(SL_PageLen, MUIA_Slider_Level, &value);
  810.             user.PageLen = (UBYTE)value;
  811.             get(SL_LineLen, MUIA_Slider_Level, &value);
  812.             user.LineLen = (UBYTE)value;
  813.             get(ST_Quota, MUIA_String_Integer, &value);
  814.             user.Quota = (UWORD)value;
  815.  
  816.             acc = 1;
  817.             user.AccessBits = 0;
  818.             for(num = 0; num < 32; num++)
  819.                {
  820.                DoMethod(LV_AccBits, MUIM_List_Select, num, MUIV_List_Select_Ask, &state);
  821.  
  822.                if(state == MUIV_List_Select_On)
  823.                   user.AccessBits |= acc;
  824.  
  825.                acc = acc << 1;
  826.                }
  827.  
  828.             user.Flags = 0;
  829.             get(CY_ReadMode, MUIA_Cycle_Active, &num);
  830.             if(num == 1)
  831.                user.Flags |= UF_RMODE_NEW;
  832.             else if(num == 2)
  833.                user.Flags |= UF_RMODE_SEL;
  834.             else if(num == 3)
  835.                user.Flags |= UF_RMODE_THRD;
  836.             get(CY_CharSet, MUIA_Cycle_Active, &num);
  837.             user.CharSet = (UBYTE)num;
  838.             get(CY_Terminal, MUIA_Cycle_Active, &num);
  839.             if(num == 1)
  840.                user.Flags |= UF_EMU_ANSI;
  841.             get(CY_Editor, MUIA_Cycle_Active, &num);
  842.             if(num == 1)
  843.                user.Flags |= UF_SCREEN_ED;
  844.  
  845.             get(CH_MsgHead, MUIA_Selected, &num);
  846.             if(num)
  847.                user.Flags |= UF_HEAD_LONG;
  848.             get(CH_Input, MUIA_Selected, &num);
  849.             if(num)
  850.                user.Flags |= UF_EDIT_INSERT;
  851.             get(CH_AutoList, MUIA_Selected, &num);
  852.             if(num)
  853.                user.Flags |= UF_AUTO_LIST;
  854.             get(CH_AutoAreaList, MUIA_Selected, &num);
  855.             if(num)
  856.                user.Flags |= UF_AUTO_AREALIST;
  857.             get(CH_WriteAcc, MUIA_Selected, &num);
  858.             if(num)
  859.                user.Flags |= UF_EXTSEND;
  860.             get(CH_ClearScreen, MUIA_Selected, &num);
  861.             if(num)
  862.                user.Flags |= UF_CLS;
  863.  
  864.             if(!addflag && strcmp(un->UserData.Name, user.Name))
  865.                {
  866.                Changes = fopen(ChangesFile, "a");
  867.                if(Changes)
  868.                   {
  869.                   fprintf(Changes, "Rename >NIL: \"%s%s\" \"%s%s\"\n", userdir, un->UserData.Name, userdir, user.Name);
  870.                   fclose(Changes);
  871.                   }
  872.                }
  873.  
  874.             un->UserData = user;
  875.  
  876.             if(addflag)
  877.                {
  878.                /* UMS-User erzeugen */
  879.  
  880.                if (AddUMSUser(un))
  881.                   {
  882.                   /* User in Liste aufnehmen */
  883.  
  884.                   DoMethod(LV_Users, MUIM_List_Insert, &un, 1, MUIV_List_Insert_Bottom);
  885.                   set(LV_Users, MUIA_List_Active, MUIV_List_Active_Bottom);
  886.  
  887.                   /* User-Directory anlegen */
  888.  
  889.                   Changes = fopen(ChangesFile, "a");
  890.                   if(Changes)
  891.                      {
  892.                      fprintf(Changes, "MakeDir >NIL: \"%s%s\"\n", userdir, user.Name);
  893.                      if (UserCheck("Default"))
  894.                         fprintf(Changes, "Copy >NIL: \"%sDefault\" \"%s%s\"\n", userdir, userdir, user.Name);
  895.                      else
  896.                         fprintf(Changes, "Copy >NIL: \"%sLOGIN.COM\" \"%s%s\"\n", userdir, userdir, user.Name);
  897.                      fclose(Changes);
  898.                      }
  899.                
  900.                   addflag = FALSE;
  901.                   }
  902.                }
  903.             else
  904.                DoMethod(LV_Users, MUIM_List_Redraw, MUIV_List_Redraw_Active);
  905.  
  906.             if(strlen(password))
  907.                {
  908.                if(!strcmp(password, " "))
  909.                   *password = '\0';
  910.  
  911.                /* Neues Paßwort in ums.config festhalten */
  912.  
  913.                WriteUMSConfigTags(SysUMSAccount, UMSTAG_CfgUser, user.RealName,
  914.                                                  UMSTAG_CfgName, "PASSWORD",
  915.                                                  UMSTAG_CfgData, password,
  916.                                                  TAG_DONE);
  917.                }
  918.  
  919.             userschanged = TRUE;
  920.  
  921.             // no break!
  922.  
  923.          case EID_CANCEL:
  924.             if(addflag)
  925.                DeleteUN(un);
  926.             addflag = FALSE;
  927.  
  928.             set(WI_Editor, MUIA_Window_Open, FALSE);
  929.             set(WI_Manager, MUIA_Window_Sleep, FALSE);
  930.  
  931.             if(Username)
  932.                DoMethod(App, MUIM_Application_ReturnID, MID_OK);
  933.    
  934.             break;
  935.          }
  936.  
  937.       if(running && signal)
  938.          Wait(signal);
  939.       }
  940.  
  941.    Sense(App, NULL);
  942.    }
  943.  
  944. ///
  945.  
  946. /*********************************
  947.  * Neue Userdatei anlegen        *
  948.  *********************************
  949.  * I: ---                        *
  950.  * O: Erfolg TRUE/FALSE          *
  951.  *********************************/
  952.  
  953. /// "InitUAF"
  954.  
  955. BOOL InitUAF(VOID)
  956.    {
  957.    FILE *file;
  958.    struct Userdaten user;
  959.    TEXT buffer[LEN_DOSPATH+1];
  960.    TEXT buff[LEN_DOSPATH*2+LEN_USERNAME+21+1];
  961.    BPTR lock;
  962.  
  963.    TakeUSem(TRUE);
  964.  
  965.    strcpy(buffer, KMSBase->DatDir);
  966.    strcat(buffer, "KMS_UAF.DAT");
  967.  
  968.    if(!(file = fopen(buffer, "w")))
  969.       {
  970.       DropUSem();
  971.       return FALSE;
  972.       }
  973.  
  974.    /* KMS-System-Account */
  975.  
  976.    clrmem(&user, sizeof(struct Userdaten));
  977.  
  978.    user.ID = 1;
  979.    user.CharSet = 0;
  980.    user.Flags = UF_EMU_ANSI|UF_EDIT_INSERT|UF_AUTO_LIST|UF_AUTO_AREALIST|UF_RMODE_NEW|UF_SCREEN_ED;
  981.    strcpy(user.Name, "System");
  982.    strcpy(user.RealName, "KMS System");
  983.    strcpy(user.City, "Ankh-Morpork");
  984.    user.Level = 255;
  985.    user.LineLen = 80;
  986.    user.PageLen = 25;
  987.    user.Quota = 10;
  988.    strcpy(user.Prompt, "System> ");
  989.  
  990.    fprintf(file, "%d\n%s\n%s\n%s\n",     user.ID,
  991.                                          user.Name,
  992.                                          user.RealName,
  993.                                          user.Street);
  994.    fprintf(file, "%s\n%s\n%s\n",         user.City,
  995.                                          user.Phone,
  996.                                          user.Prompt);
  997.    fprintf(file, "%d\n%d\n%ld\n",        user.Level,
  998.                                          user.Calls,
  999.                                          user.LastCall);
  1000.    fprintf(file, "%d\n%d\n%d\n%d\n",     user.CharSet,
  1001.                                          user.PageLen,
  1002.                                          user.LineLen,
  1003.                                          user.Protocol);
  1004.    fprintf(file, "%ld\n%ld\n%d\n \n",    user.Flags,
  1005.                                          user.AccessBits,
  1006.                                          user.Quota);
  1007.  
  1008.    /* Leeres Paßwort in ums.config festhalten */
  1009.  
  1010.    WriteUMSConfigTags(SysUMSAccount, UMSTAG_CfgUser, user.RealName,
  1011.                                      UMSTAG_CfgName, "PASSWORD",
  1012.                                      UMSTAG_CfgData, "",
  1013.                                      TAG_DONE);
  1014.  
  1015.    /* User-Directory anlegen */
  1016.  
  1017.    strcpy(buffer, KMSBase->UserDir);
  1018.    strcat(buffer, user.Name);
  1019.  
  1020.    if(lock = CreateDir(buffer))
  1021.       {
  1022.       UnLock(lock);
  1023.  
  1024.       /* LOGIN.COM kopieren */
  1025.  
  1026.       sprintf(buff, "Copy >NIL: %sLOGIN.COM %s", KMSBase->UserDir, buffer);
  1027.       system(buff);
  1028.       }
  1029.  
  1030.    /* KMS-Default-Account */
  1031.  
  1032.    clrmem(&user, sizeof(struct Userdaten));
  1033.  
  1034.    user.ID = 2;
  1035.    user.CharSet = 0;
  1036.    user.Flags = UF_EMU_ANSI|UF_EDIT_INSERT|UF_AUTO_LIST|UF_AUTO_AREALIST|UF_RMODE_NEW|UF_SCREEN_ED;
  1037.    strcpy(user.Name, "Default");
  1038.    strcpy(user.RealName, "KMS Default");
  1039.    strcpy(user.City, "Pern");
  1040.    user.Level = 10;
  1041.    user.LineLen = 80;
  1042.    user.PageLen = 25;
  1043.    user.Quota = 10;
  1044.    strcpy(user.Prompt, "[%p]> ");
  1045.  
  1046.    fprintf(file, "%d\n%s\n%s\n%s\n",     user.ID,
  1047.                                          user.Name,
  1048.                                          user.RealName,
  1049.                                          user.Street);
  1050.    fprintf(file, "%s\n%s\n%s\n",         user.City,
  1051.                                          user.Phone,
  1052.                                          user.Prompt);
  1053.    fprintf(file, "%d\n%d\n%ld\n",        user.Level,
  1054.                                          user.Calls,
  1055.                                          user.LastCall);
  1056.    fprintf(file, "%d\n%d\n%d\n%d\n",     user.CharSet,
  1057.                                          user.PageLen,
  1058.                                          user.LineLen,
  1059.                                          user.Protocol);
  1060.    fprintf(file, "%ld\n%ld\n%d\n\n",     user.Flags,
  1061.                                          user.AccessBits,
  1062.                                          user.Quota);
  1063.  
  1064.    /* Leeres Paßwort in ums.config festhalten */
  1065.  
  1066.    WriteUMSConfigTags(SysUMSAccount, UMSTAG_CfgUser, user.RealName,
  1067.                                      UMSTAG_CfgName, "PASSWORD",
  1068.                                      UMSTAG_CfgData, "",
  1069.                                      TAG_DONE);
  1070.  
  1071.    /* User-Directory anlegen */
  1072.  
  1073.    strcpy(buffer, KMSBase->UserDir);
  1074.    strcat(buffer, user.Name);
  1075.  
  1076.    if (lock = CreateDir(buffer))
  1077.       {
  1078.       UnLock(lock);
  1079.  
  1080.       /* LOGIN.COM kopieren */
  1081.  
  1082.       sprintf(buff, "Copy >NIL: %sLOGIN.COM %s", KMSBase->UserDir, buffer);
  1083.       system(buff);
  1084.       }
  1085.  
  1086.    /* GAST-Account */
  1087.  
  1088.    clrmem(&user, sizeof(struct Userdaten));
  1089.  
  1090.    user.ID = 3;
  1091.    user.CharSet = 0;
  1092.    user.Flags = UF_EMU_ANSI|UF_EDIT_INSERT|UF_AUTO_LIST|UF_AUTO_AREALIST|UF_RMODE_NEW|UF_SCREEN_ED;
  1093.    strcpy(user.Name, "Gast");
  1094.    strcpy(user.RealName, "KMS Gast");
  1095.    strcpy(user.City, "Ankh-Morpork");
  1096.    user.Level = 1;
  1097.    user.LineLen = 80;
  1098.    user.PageLen = 25;
  1099.    user.Quota = 0;
  1100.    strcpy(user.Prompt, "[%p]> ");
  1101.  
  1102.    fprintf(file, "%d\n%s\n%s\n%s\n",     user.ID,
  1103.                                          user.Name,
  1104.                                          user.RealName,
  1105.                                          user.Street);
  1106.    fprintf(file, "%s\n%s\n%s\n",         user.City,
  1107.                                          user.Phone,
  1108.                                          user.Prompt);
  1109.    fprintf(file, "%d\n%d\n%ld\n",        user.Level,
  1110.                                          user.Calls,
  1111.                                          user.LastCall);
  1112.    fprintf(file, "%d\n%d\n%d\n%d\n",     user.CharSet,
  1113.                                          user.PageLen,
  1114.                                          user.LineLen,
  1115.                                          user.Protocol);
  1116.    fprintf(file, "%ld\n%ld\n%d\n \n",    user.Flags,
  1117.                                          user.AccessBits,
  1118.                                          user.Quota);
  1119.  
  1120.    /* Leeres Paßwort in ums.config festhalten */
  1121.  
  1122.    WriteUMSConfigTags(SysUMSAccount, UMSTAG_CfgUser, user.RealName,
  1123.                                      UMSTAG_CfgName, "PASSWORD",
  1124.                                      UMSTAG_CfgData, "",
  1125.                                      TAG_DONE);
  1126.  
  1127.    /* User-Directory anlegen */
  1128.  
  1129.    strcpy(buffer, KMSBase->UserDir);
  1130.    strcat(buffer, user.Name);
  1131.  
  1132.    if(lock = CreateDir(buffer))
  1133.       UnLock(lock);
  1134.  
  1135.    fclose(file);
  1136.  
  1137.    DropUSem();
  1138.  
  1139.    return TRUE;
  1140.    }
  1141.  
  1142. ///
  1143.  
  1144. /*********************************
  1145.  * UserList einlesen             *
  1146.  *********************************
  1147.  * I: ---                        *
  1148.  * O: Erfolg? TRUE/FALSE         *
  1149.  *********************************/
  1150.  
  1151. /// "ReadUserList"
  1152.  
  1153. BOOL ReadUserList(VOID)
  1154.    {
  1155.    struct UserNode *upoint;
  1156.    struct Userdaten user;
  1157.    TEXT buffer[LEN_DOSPATH+1];
  1158.    TEXT buff[LEN_REALNAME+2]; /* RealName ist eines der laengsten Elemente */
  1159.    FILE *file;
  1160.  
  1161.    /* Wenn schon eingelesen, fertig */
  1162.  
  1163.    upoint = (struct UserNode *)KMSBase->UserList.mlh_Head;
  1164.    if(upoint->Node.mln_Succ)
  1165.       return TRUE;
  1166.  
  1167.    /* Einlesen */
  1168.  
  1169.    TakeUSem(TRUE);
  1170.  
  1171.    strcpy(buffer, KMSBase->DatDir);
  1172.    strcat(buffer, "KMS_UAF.DAT");
  1173.  
  1174.    if(!(file = fopen(buffer, "r")))
  1175.       {
  1176.       DropUSem();
  1177.       return FALSE;
  1178.       }
  1179.    else
  1180.       {
  1181.       while(fgets(buff, LEN_NUMBER+2, file))
  1182.          {
  1183.          if(!(upoint = (struct UserNode *)AllocMem((ULONG)sizeof(struct UserNode), MEMF_PUBLIC|MEMF_CLEAR)))
  1184.             {
  1185.             Error("out of memory.");
  1186.  
  1187.             fclose(file);
  1188.             DropUSem();
  1189.             return FALSE;
  1190.             }
  1191.  
  1192.          clrmem(&user, sizeof(struct Userdaten));
  1193.  
  1194.          user.ID = (UWORD)atoi(buff);
  1195.          if(fgets(buff, LEN_USERNAME+2, file))
  1196.             {
  1197.             if(strlen(buff))
  1198.                buff[strlen(buff)-1] = '\0'; /* Linefeed am Ende entfernen */
  1199.             strcpy(user.Name, buff);
  1200.             }
  1201.          if(fgets(buff, LEN_REALNAME+2, file))
  1202.             {
  1203.             if(strlen(buff))
  1204.                buff[strlen(buff)-1] = '\0'; /* Linefeed am Ende entfernen */
  1205.             strcpy(user.RealName, buff);
  1206.             }
  1207.          if(fgets(buff, LEN_STREET+2, file))
  1208.             {
  1209.             if(strlen(buff))
  1210.                buff[strlen(buff)-1] = '\0'; /* Linefeed am Ende entfernen */
  1211.             strcpy(user.Street, buff);
  1212.             }
  1213.          if(fgets(buff, LEN_CITY+2, file))
  1214.             {
  1215.             if(strlen(buff))
  1216.                buff[strlen(buff)-1] = '\0'; /* Linefeed am Ende entfernen */
  1217.             strcpy(user.City, buff);
  1218.             }
  1219.          if(fgets(buff, LEN_PHONE+2, file))
  1220.             {
  1221.             if(strlen(buff))
  1222.                buff[strlen(buff)-1] = '\0';
  1223.             strcpy(user.Phone, buff);
  1224.             }
  1225.          if(fgets(buff, LEN_UPROMPT+2, file))
  1226.             {
  1227.             if(strlen(buff))
  1228.                buff[strlen(buff)-1] = '\0';
  1229.             strcpy(user.Prompt, buff);
  1230.             }
  1231.          if(fgets(buff, LEN_NUMBER+2, file))
  1232.             user.Level = (UWORD)atoi(buff);
  1233.          if(fgets(buff, LEN_NUMBER+2, file))
  1234.             user.Calls = (UWORD)atoi(buff);
  1235.          if(fgets(buff, LEN_NUMBER+2, file))
  1236.             user.LastCall = (ULONG)atol(buff);
  1237.          if(fgets(buff, LEN_NUMBER+2, file))
  1238.             user.CharSet = (UBYTE)atoi(buff);
  1239.          if(fgets(buff, LEN_NUMBER+2, file))
  1240.             user.PageLen = (UBYTE)atoi(buff);
  1241.          if(fgets(buff, LEN_NUMBER+2, file))
  1242.             user.LineLen = (UBYTE)atoi(buff);
  1243.          if(fgets(buff, LEN_NUMBER+2, file))
  1244.             user.Protocol = (UBYTE)atoi(buff);
  1245.          if(fgets(buff, LEN_NUMBER+2, file))
  1246.             user.Flags = (ULONG)atol(buff);
  1247.          if(fgets(buff, LEN_NUMBER+2, file))
  1248.             user.AccessBits = (ULONG)atol(buff);
  1249.          if(fgets(buff, LEN_NUMBER+2, file))
  1250.             user.Quota = (UWORD)atoi(buff);
  1251.          if(fgets(buff, 15+2, file))
  1252.             {
  1253.             if(strlen(buff))
  1254.                buff[strlen(buff)-1] = '\0';
  1255.             }
  1256.  
  1257.          upoint->UserData = user;
  1258.  
  1259.          AddTail((struct List *)&KMSBase->UserList, (struct Node *)upoint);
  1260.          }
  1261.  
  1262.       fclose(file);
  1263.       }
  1264.  
  1265.    DropUSem();
  1266.  
  1267.    return TRUE;
  1268.    }
  1269.  
  1270. ///
  1271.  
  1272. /*********************************
  1273.  * UserList schreiben            *
  1274.  *********************************
  1275.  * I: ---                        *
  1276.  * O: Erfolg? TRUE/FALSE         *
  1277.  *********************************/
  1278.  
  1279. /// "WriteUserList"
  1280.  
  1281. /*
  1282. struct Userdaten
  1283.    {
  1284.    UWORD ID;
  1285.    TEXT  Name[LEN_USERNAME+1];
  1286.    TEXT  RealName[LEN_REALNAME+1];
  1287.    TEXT  Street[LEN_STREET+1];
  1288.    TEXT  City[LEN_CITY+1];
  1289.    TEXT  Phone[LEN_PHONE+1];
  1290.    TEXT  Prompt[LEN_UPROMPT+1];
  1291.    UWORD Level;
  1292.    UWORD Calls;
  1293.    time_t LastCall;
  1294.    UBYTE CharSet;
  1295.    UBYTE PageLen;
  1296.    UBYTE LineLen;
  1297.    UBYTE Protocol;
  1298.    ULONG Flags;
  1299.    ULONG AccessBits;
  1300.    UWORD Quota;
  1301.    };
  1302. */
  1303.  
  1304. BOOL WriteUserList(VOID)
  1305.    {
  1306.    struct UserNode *upoint;
  1307.    TEXT buffer[LEN_DOSPATH+1];
  1308.    FILE *file;
  1309.    ULONG num;
  1310.  
  1311.    strcpy(buffer, KMSBase->DatDir);
  1312.    strcat(buffer, "KMS_UAF.DAT");
  1313.  
  1314.    TakeUSem(TRUE);
  1315.  
  1316.    file = fopen(buffer, "w");
  1317.    if(!file)
  1318.       {
  1319.       DropUSem();
  1320.       return FALSE;
  1321.       }
  1322.  
  1323.    for(num = 0; ; num++)
  1324.       {
  1325.       DoMethod(LV_Users, MUIM_List_GetEntry, num, &upoint);
  1326.       if(!upoint)
  1327.          break;
  1328.  
  1329.       upoint->UserData.ID = num + 1;
  1330.  
  1331.       fprintf(file,"%d\n%s\n%s\n%s\n",     upoint->UserData.ID,
  1332.                                            upoint->UserData.Name,
  1333.                                            upoint->UserData.RealName,
  1334.                                            upoint->UserData.Street);
  1335.       fprintf(file,"%s\n%s\n%s\n",         upoint->UserData.City,
  1336.                                            upoint->UserData.Phone,
  1337.                                            upoint->UserData.Prompt);
  1338.       fprintf(file,"%d\n%d\n%ld\n",        upoint->UserData.Level,
  1339.                                            upoint->UserData.Calls,
  1340.                                            upoint->UserData.LastCall);
  1341.       fprintf(file,"%d\n%d\n%d\n%d\n",     upoint->UserData.CharSet,
  1342.                                            upoint->UserData.PageLen,
  1343.                                            upoint->UserData.LineLen,
  1344.                                            upoint->UserData.Protocol);
  1345.       fprintf(file,"%ld\n%ld\n%d\n\n",     upoint->UserData.Flags,
  1346.                                            upoint->UserData.AccessBits,
  1347.                                            upoint->UserData.Quota);
  1348.       }
  1349.  
  1350.    fclose(file);
  1351.  
  1352.    DropUSem();
  1353.  
  1354.    return TRUE;
  1355.    }
  1356.  
  1357. ///
  1358.  
  1359. /********************************
  1360.  * Neuen UserNode einrichten    *
  1361.  ********************************
  1362.  * I: ---                       *
  1363.  * O: struct UserNode *         *
  1364.  ********************************/
  1365.  
  1366. /// "AddUN"
  1367.  
  1368. struct UserNode *AddUN(VOID)
  1369.    {
  1370.    struct UserNode *upoint, *newupoint;
  1371.    UWORD id, maxid;
  1372.  
  1373.    upoint = (struct UserNode *)KMSBase->UserList.mlh_TailPred;
  1374.    if(!upoint->Node.mln_Pred)
  1375.       {
  1376.       MUI_RequestA(App, NULL, 0, "KMSUM Error", "I see", "No UserList!?", NULL);
  1377.       return NULL;
  1378.       }
  1379.  
  1380.    maxid = 0; id = 0;
  1381.    upoint = (struct UserNode *)KMSBase->UserList.mlh_Head;
  1382.    while(upoint->Node.mln_Succ)
  1383.       {
  1384.       id = upoint->UserData.ID;
  1385.       if(id > maxid)
  1386.          maxid = id;
  1387.  
  1388.       upoint = (struct UserNode *)upoint->Node.mln_Succ;
  1389.       }
  1390.  
  1391.    maxid++;
  1392.  
  1393.    if(maxid == 0) /* Überlauf */
  1394.       {
  1395.       MUI_RequestA(App, NULL, 0, "KMSUM Error", "I see", "Too many users!", NULL);
  1396.       return NULL;
  1397.       }
  1398.  
  1399.    if(!(newupoint = (struct UserNode *)AllocMem((ULONG)sizeof(struct UserNode), MEMF_PUBLIC|MEMF_CLEAR)))
  1400.       {
  1401.       MUI_RequestA(App, NULL, 0, "KMSUM Error", "I see", "Out of memory!", NULL);
  1402.       return NULL;
  1403.       }
  1404.  
  1405.    newupoint->UserData.ID = maxid;
  1406.  
  1407.    AddTail((struct List *)&KMSBase->UserList, (struct Node *)newupoint);
  1408.  
  1409.    return newupoint;
  1410.    }
  1411.  
  1412. ///
  1413.  
  1414. /********************************
  1415.  * UserNode löschen             *
  1416.  ********************************
  1417.  * I: struct UserNode *         *
  1418.  * O: ---                       *
  1419.  ********************************/
  1420.  
  1421. /// "DeleteUN"
  1422.  
  1423. VOID DeleteUN(struct UserNode *un)
  1424.    {
  1425.    if(!un)
  1426.       return;
  1427.  
  1428.    Remove((struct Node *)un);
  1429.  
  1430.    FreeMem(un, (ULONG)sizeof(struct UserNode));
  1431.    }
  1432.  
  1433. ///
  1434.  
  1435. /**********************************
  1436.  * Username auf Gültigkeit prüfen *
  1437.  **********************************
  1438.  * I: Name                        *
  1439.  * O: struct UserNode *           *
  1440.  **********************************/
  1441.  
  1442. /// "UserCheck"
  1443.  
  1444. struct UserNode *UserCheck(STRPTR name)
  1445.    {
  1446.    struct UserNode *upoint;
  1447.  
  1448.    if(!name || !strlen(name))
  1449.       return NULL;
  1450.  
  1451.    ConvertSpace(name);
  1452.  
  1453.    TakeUSem(FALSE);
  1454.    upoint = (struct UserNode *)KMSBase->UserList.mlh_Head;
  1455.    while(upoint->Node.mln_Succ)
  1456.       {
  1457.       if(!stricmp(name, upoint->UserData.Name))
  1458.          {
  1459.          DropUSem();
  1460.          return upoint;
  1461.          }
  1462.  
  1463.       upoint = upoint->Node.mln_Succ;
  1464.       }
  1465.  
  1466.    DropUSem();
  1467.  
  1468.    return NULL;
  1469.    }
  1470.  
  1471. ///
  1472.  
  1473. /****************************
  1474.  * Parse Arguments          *
  1475.  ****************************
  1476.  * I: ---                   *
  1477.  * O: Error: FALSE Ok: TRUE *
  1478.  ****************************/
  1479.  
  1480. /// "ParseArgs"
  1481.  
  1482. #define TEMPLATE "USERNAME"
  1483.  
  1484. STRPTR HelpTxt = "\nUsage:\n\nUSERNAME      optional: User to edit\n\n";
  1485.  
  1486. BOOL ParseArgs(VOID)
  1487.    {
  1488.    UBYTE n;
  1489.    ULONG args[1];
  1490.    struct RDArgs *rargs = NULL;
  1491.    struct RDArgs *myrdargs = NULL;
  1492.  
  1493.    for(n = 0; n < 1; n++)
  1494.       args[n] = 0;
  1495.  
  1496.    myrdargs = AllocDosObjectTags(DOS_RDARGS, TAG_DONE);
  1497.    if(!myrdargs)
  1498.       {
  1499.       PrintFault(IoErr(), NULL);
  1500.       return FALSE;
  1501.       }
  1502.  
  1503.    myrdargs->RDA_ExtHelp = HelpTxt;
  1504.  
  1505.    if(!(rargs = (struct RDArgs *)ReadArgs(TEMPLATE, args, myrdargs)))
  1506.       {
  1507.       PrintFault(IoErr(), NULL);
  1508.       FreeDosObject(DOS_RDARGS, myrdargs);
  1509.       return FALSE;
  1510.       }
  1511.  
  1512.    if(args[0]) /* USERNAME */
  1513.       {
  1514.       Username = (STRPTR)strdup((STRPTR)args[0]);
  1515.       ConvertSpace(Username);
  1516.       }
  1517.  
  1518.    FreeArgs(rargs);
  1519.    FreeDosObject(DOS_RDARGS, myrdargs);
  1520.  
  1521.    return TRUE;
  1522.    }
  1523.  
  1524. ///
  1525.  
  1526. /****************************
  1527.  * Sense                    *
  1528.  ****************************
  1529.  * I: ---                   *
  1530.  * O: ---                   *
  1531.  ****************************/
  1532.  
  1533. /// "Sense"
  1534.  
  1535. VOID Sense(APTR app, STRPTR str)
  1536.    {
  1537.    if(app)
  1538.       MUI_DisposeObject(app);
  1539.    if(Username)
  1540.       free(Username);
  1541.    
  1542.    if(KMSBase)
  1543.       {
  1544.       /* Von der Basis abmelden */
  1545.  
  1546.       ReleaseSemaphore(&KMSBase->BaseSem);
  1547.  
  1548.       /* KMSBase gegebenenfalls wieder entfernen */
  1549.  
  1550.       Forbid();
  1551.  
  1552.       if(KMSBase = (struct KMSBase *)FindSemaphore(KMSBASENAME))
  1553.          {
  1554.          if(AttemptSemaphore(&KMSBase->BaseSem))
  1555.             {
  1556.             Permit();
  1557.  
  1558.             /* Arealiste freigeben */
  1559.  
  1560.             struct AreaNode *apoint = KMSBase->AreaList.mlh_Head;
  1561.             while(apoint->Node.mln_Succ)
  1562.                {
  1563.                struct AreaNode *nextapoint = apoint->Node.mln_Succ;
  1564.                Remove((struct Node *)apoint);
  1565.                FreeMem(apoint, (ULONG)sizeof(struct AreaNode));
  1566.                apoint = nextapoint;
  1567.                }
  1568.  
  1569.             /* Userliste freigeben */
  1570.  
  1571.             struct UserNode *upoint = KMSBase->UserList.mlh_Head;
  1572.             while(upoint->Node.mln_Succ)
  1573.                {
  1574.                struct UserNode *nextupoint = upoint->Node.mln_Succ;
  1575.                Remove((struct Node *)upoint);
  1576.                FreeMem(upoint, (ULONG)sizeof(struct UserNode));
  1577.                upoint = nextupoint;
  1578.                }
  1579.  
  1580.             if(KMSBase->DatDir)
  1581.                FreeMem(KMSBase->DatDir, strlen(KMSBase->DatDir) + 1);
  1582.             if(KMSBase->UserDir)
  1583.                FreeMem(KMSBase->UserDir, strlen(KMSBase->UserDir) + 1);
  1584.  
  1585.             RemSemaphore(&KMSBase->BaseSem);
  1586.  
  1587.             ObtainSemaphore(&KMSBase->UserSem);
  1588.             ReleaseSemaphore(&KMSBase->UserSem);
  1589.             ObtainSemaphore(&KMSBase->AreaSem);
  1590.             ReleaseSemaphore(&KMSBase->AreaSem);
  1591.             ObtainSemaphore(&KMSBase->SaveSem);
  1592.             ReleaseSemaphore(&KMSBase->SaveSem);
  1593.  
  1594.             ReleaseSemaphore(&KMSBase->BaseSem);
  1595.  
  1596.             FreeMem(KMSBase->BaseSem.ss_Link.ln_Name, sizeof(KMSBASENAME)+1);
  1597.  
  1598.             FreeMem(KMSBase, sizeof(struct KMSBase));
  1599.             }
  1600.          else
  1601.             Permit();
  1602.          }
  1603.       else
  1604.          Permit();
  1605.       }
  1606.  
  1607.    if(UMSBase)
  1608.       {
  1609.       if(SysUMSAccount)
  1610.          UMSLogout(SysUMSAccount);
  1611.       CloseLibrary(UMSBase);
  1612.       }
  1613.  
  1614.    if(str)
  1615.       {
  1616.       fputs(str, stderr);
  1617.       fputs("\n", stderr);
  1618.       exit(20);
  1619.       }
  1620.  
  1621.    if(ChangesFile && strlen(ChangesFile))
  1622.       DeleteFile(ChangesFile);
  1623.  
  1624.    exit(0);
  1625.    }
  1626.  
  1627. ///
  1628.  
  1629. /****************************
  1630.  * AccessBits einlesen      *
  1631.  ****************************
  1632.  * I: ---                   *
  1633.  * O: ---                   *
  1634.  ****************************/
  1635.  
  1636. /// "ReadAccBits"
  1637.  
  1638. VOID ReadAccBits(VOID)
  1639.    {
  1640.    TEXT dos[LEN_DOSPATH+1];
  1641.    TEXT buff[LEN_NUMBER+LEN_ACCBITNAME+2];
  1642.    UWORD n;
  1643.    FILE *datei;
  1644.  
  1645.    strcpy(dos, KMSBase->DatDir);
  1646.    strcat(dos, "KMS_SYSTEM.DAT");
  1647.  
  1648.    ObtainSemaphore(&KMSBase->SaveSem);
  1649.  
  1650.    SystemStartups = 1;
  1651.    for(n = 0; n < 32; n++)
  1652.       sprintf(AccBitNames[n], "[Bit#%02d]", n+1);
  1653.  
  1654.    if(datei = fopen(dos, "r"))
  1655.       {
  1656.       fgets(buff, LEN_NUMBER+2, datei);
  1657.       SystemStartups = atol(buff) + 1;
  1658.  
  1659.       for(n = 0; n < 32; n++)
  1660.          {
  1661.          *buff = '\0';
  1662.          if(fgets(buff, LEN_ACCBITNAME+2, datei))
  1663.             buff[strlen(buff)-1] = '\0';
  1664.  
  1665.          if(!strlen(buff))
  1666.             sprintf(AccBitNames[n], "[Bit#%02d]", n+1);
  1667.          else
  1668.             strcpy(AccBitNames[n], buff);
  1669.          }
  1670.  
  1671.       fclose(datei);
  1672.       }
  1673.  
  1674.    ReleaseSemaphore(&KMSBase->SaveSem);
  1675.    }
  1676.  
  1677. ///
  1678.  
  1679. /***************************
  1680.  * AccessBits speichern    *
  1681.  ***************************
  1682.  * I: ---                  *
  1683.  * O: Erfolg TRUE/FALSE    *
  1684.  ***************************/
  1685.  
  1686. /// "WriteAccBits"
  1687.  
  1688. BOOL WriteAccBits(VOID)
  1689.    {
  1690.    FILE *datei;
  1691.    TEXT dos[LEN_DOSPATH+1];
  1692.    UBYTE n;
  1693.  
  1694.    ObtainSemaphore(&KMSBase->SaveSem);
  1695.  
  1696.    strcpy(dos, KMSBase->DatDir);
  1697.    strcat(dos, "KMS_SYSTEM.DAT");
  1698.  
  1699.    datei = fopen(dos, "w");
  1700.    if(datei)
  1701.       {
  1702.       fprintf(datei, "%ld\n", SystemStartups);
  1703.       for(n = 0; n < 32; n++)
  1704.          fprintf(datei, "%s\n", AccBitNames[n]);
  1705.  
  1706.       fclose(datei);
  1707.       }
  1708.  
  1709.    ReleaseSemaphore(&KMSBase->SaveSem);
  1710.  
  1711.    if(datei)
  1712.       return TRUE;
  1713.    else
  1714.       return FALSE;
  1715.    }
  1716.  
  1717. ///
  1718.  
  1719. /***************************
  1720.  * "Execute Changes"       *
  1721.  ***************************
  1722.  * I: ---                  *
  1723.  * O: Erfolg TRUE/FALSE    *
  1724.  ***************************/
  1725.  
  1726. /// "MakeChanges"
  1727.  
  1728. BOOL MakeChanges(VOID)
  1729.    {
  1730.    TEXT buff[256];
  1731.    FILE *file;
  1732.  
  1733.    if(file = fopen(ChangesFile, "r"))
  1734.       {
  1735.       fclose(file);
  1736.  
  1737.       sprintf(buff, "Execute %s", ChangesFile);
  1738.       system(buff);
  1739.       }
  1740.  
  1741.    return TRUE;
  1742.    }
  1743.  
  1744. ///
  1745.  
  1746. /********************************
  1747.  * KMSBase besorgen             *
  1748.  ********************************
  1749.  * I: ---                       *
  1750.  * O: struct KMSBase *          *
  1751.  ********************************/
  1752.  
  1753. /// "GetKMSBase"
  1754.  
  1755. struct KMSBase *GetKMSBase(VOID)
  1756.    {
  1757.    STRPTR bname;
  1758.    STRPTR string;
  1759.  
  1760.    UMSBase = (struct Library *)OpenLibrary(UMSNAME, 0);
  1761.    if(!UMSBase)
  1762.       {
  1763.       Error("couldn't open ums.library.");
  1764.       return NULL;
  1765.       }
  1766.  
  1767.    TEXT varbuff[32] = "";
  1768.    TEXT pwbuff[32] = "";
  1769.    GetVar("KMSMB", varbuff, sizeof(varbuff), NULL);
  1770.    GetVar("KMSPWD", pwbuff, sizeof(pwbuff), NULL);
  1771.    if(!(SysUMSAccount = UMSRLogin(varbuff, "KMS", pwbuff)))
  1772.       {
  1773.       Error("couldn't log into UMS.");
  1774.       return NULL;
  1775.       }
  1776.  
  1777.    /* KMSBase erzeugen, falls nicht vorhanden */
  1778.  
  1779.    Forbid();
  1780.  
  1781.    if(!(KMSBase = (struct KMSBase *)FindSemaphore(KMSBASENAME)))
  1782.       {
  1783.       bname = AllocMem((ULONG)sizeof(KMSBASENAME)+1, MEMF_PUBLIC|MEMF_CLEAR);
  1784.       if(bname)
  1785.          {
  1786.          strcpy(bname, KMSBASENAME);
  1787.  
  1788.          if(KMSBase = AllocMem((ULONG)sizeof(struct KMSBase), MEMF_PUBLIC|MEMF_CLEAR))
  1789.             {
  1790.             KMSBase->BaseSem.ss_Link.ln_Pri = 0;
  1791.             KMSBase->BaseSem.ss_Link.ln_Name = bname;
  1792.             KMSBase->UserSem.ss_Link.ln_Pri = 0;
  1793.             KMSBase->UserSem.ss_Link.ln_Name = NULL;
  1794.             KMSBase->AreaSem.ss_Link.ln_Pri = 0;
  1795.             KMSBase->AreaSem.ss_Link.ln_Name = NULL;
  1796.             KMSBase->SaveSem.ss_Link.ln_Pri = 0;
  1797.             KMSBase->SaveSem.ss_Link.ln_Name = NULL;
  1798.  
  1799.             NewList((struct List *)&KMSBase->AreaList);
  1800.             NewList((struct List *)&KMSBase->UserList);
  1801.  
  1802.             AddSemaphore(&KMSBase->BaseSem);
  1803.             InitSemaphore(&KMSBase->UserSem);
  1804.             InitSemaphore(&KMSBase->AreaSem);
  1805.             InitSemaphore(&KMSBase->SaveSem);
  1806.  
  1807.             ObtainSemaphore(&KMSBase->BaseSem);
  1808.  
  1809.             Permit();
  1810.  
  1811.             if(string = ReadUMSConfigTags(SysUMSAccount, UMSTAG_CfgName, "KMS.datdir", TAG_DONE))
  1812.                {
  1813.                KMSBase->DatDir = AllocMem((ULONG)(strlen(string)+1), MEMF_PUBLIC|MEMF_CLEAR);
  1814.                if(KMSBase->DatDir)
  1815.                   strcpy(KMSBase->DatDir, string);
  1816.  
  1817.                FreeUMSConfig(SysUMSAccount, string);
  1818.  
  1819.                if(!KMSBase->DatDir)
  1820.                   {
  1821.                   Error("out of memory.");
  1822.                   return NULL;
  1823.                   }
  1824.                }
  1825.             else
  1826.                {
  1827.                KMSBase->DatDir = AllocMem((ULONG)(strlen("Data/")+1), MEMF_PUBLIC|MEMF_CLEAR);
  1828.                if(KMSBase->DatDir)
  1829.                   strcpy(KMSBase->DatDir, "Data/");
  1830.                else
  1831.                   {
  1832.                   Error("out of memory.");
  1833.                   return NULL;
  1834.                   }
  1835.                }
  1836.  
  1837.             if(string = ReadUMSConfigTags(SysUMSAccount, UMSTAG_CfgName, "KMS.userdir", TAG_DONE))
  1838.                {
  1839.                KMSBase->UserDir = AllocMem((ULONG)(strlen(string)+1), MEMF_PUBLIC|MEMF_CLEAR);
  1840.                if(KMSBase->UserDir)
  1841.                   strcpy(KMSBase->UserDir, string);
  1842.  
  1843.                FreeUMSConfig(SysUMSAccount, string);
  1844.  
  1845.                if(!KMSBase->UserDir)
  1846.                   {
  1847.                   Error("out of memory.");
  1848.                   return NULL;
  1849.                   }
  1850.                }
  1851.             else
  1852.                {
  1853.                KMSBase->UserDir = AllocMem((ULONG)(strlen("User/")+1), MEMF_PUBLIC|MEMF_CLEAR);
  1854.                if(KMSBase->UserDir)
  1855.                   strcpy(KMSBase->UserDir, "User/");
  1856.                else
  1857.                   {
  1858.                   Error("out of memory.");
  1859.                   return NULL;
  1860.                   }
  1861.                }
  1862.  
  1863.             ReleaseSemaphore(&KMSBase->BaseSem);
  1864.             ObtainSemaphoreShared(&KMSBase->BaseSem);
  1865.             }
  1866.          else
  1867.             {
  1868.             Permit();
  1869.  
  1870.             if(bname)
  1871.                FreeMem(bname, sizeof(KMSBASENAME)+1);
  1872.  
  1873.             Error("out of memory.");
  1874.  
  1875.             return NULL;
  1876.             }
  1877.          }
  1878.       else
  1879.          {
  1880.          Permit();
  1881.  
  1882.          Error("out of memory.");
  1883.  
  1884.          return NULL;
  1885.          }
  1886.       }
  1887.    else
  1888.       {
  1889.       Permit();
  1890.  
  1891.       ObtainSemaphoreShared(&KMSBase->BaseSem);
  1892.       }
  1893.  
  1894.    /* Userliste einlesen oder anlegen, falls nicht vorhanden */
  1895.  
  1896.    if(!ReadUserList())
  1897.       {
  1898.       InitUAF();
  1899.       if(!ReadUserList())
  1900.          {
  1901.          Error("couldn't create or read KMS_UAF.DAT");
  1902.          return NULL;
  1903.          }
  1904.       }
  1905.  
  1906.    ReadAccBits();
  1907.  
  1908.    return KMSBase;
  1909.    }
  1910.  
  1911. ///
  1912.  
  1913. /********************************
  1914.  * Standardfehlerausgabe        *
  1915.  ********************************
  1916.  * I: ---                       *
  1917.  * O: ---                       *
  1918.  ********************************/
  1919.  
  1920. /// "Error"
  1921.  
  1922. VOID Error(STRPTR errtxt)
  1923.    {
  1924.    if(errtxt)
  1925.       {
  1926.       fputs(errtxt, stderr);
  1927.       fputs("\n", stderr);
  1928.       }
  1929.    }
  1930.  
  1931. ///
  1932.  
  1933. /********************************
  1934.  * Leerzeichen -> Underscore    *
  1935.  ********************************
  1936.  * I: STRPTR                    *
  1937.  * O: ---                       *
  1938.  ********************************/
  1939.  
  1940. /// "ConvertSpace"
  1941.  
  1942. VOID ConvertSpace(STRPTR string)
  1943.    {
  1944.    if(!string)
  1945.       return;
  1946.  
  1947.    while(*string)
  1948.       {
  1949.       if(*string == ' ')
  1950.          *string = '_';
  1951.  
  1952.       string++;
  1953.       }
  1954.    }
  1955.  
  1956. ///
  1957.  
  1958. /// "TakeUSem"
  1959.  
  1960. VOID TakeUSem(BOOL exclusive)
  1961.    {
  1962.    if(exclusive)
  1963.       ObtainSemaphore(&KMSBase->UserSem);
  1964.    else
  1965.       ObtainSemaphoreShared(&KMSBase->UserSem);
  1966.    }
  1967.  
  1968. ///
  1969.  
  1970. /// "DropUSem"
  1971.  
  1972. VOID DropUSem(VOID)
  1973.    {
  1974.    ReleaseSemaphore(&KMSBase->UserSem);
  1975.    }
  1976.  
  1977. ///
  1978.  
  1979. /// "TakeMSem"
  1980.  
  1981. VOID TakeMSem(BOOL exclusive)
  1982.    {
  1983.    if(exclusive)
  1984.       ObtainSemaphore(&KMSBase->SaveSem);
  1985.    else
  1986.       ObtainSemaphoreShared(&KMSBase->SaveSem);
  1987.    }
  1988.  
  1989. ///
  1990.  
  1991. /// "DropMSem"
  1992.  
  1993. VOID DropMSem(VOID)
  1994.    {
  1995.    ReleaseSemaphore(&KMSBase->SaveSem);
  1996.    }
  1997.  
  1998. ///
  1999.  
  2000. /********************************
  2001.  * UMS-Usereintrag erzeugen     *
  2002.  ********************************
  2003.  * I: struct UserNode *         *
  2004.  * O: Erfolg TRUE/FALSE         *
  2005.  ********************************/
  2006.  
  2007. /// AddUMSUser
  2008.  
  2009. BOOL AddUMSUser(struct UserNode *unode)
  2010.    {
  2011.    if (!WriteUMSConfigTags(SysUMSAccount, UMSTAG_CfgCreateUser, unode->UserData.RealName,
  2012.                                           TAG_DONE))
  2013.       return FALSE;
  2014.  
  2015.    if (WriteUMSConfigTags(SysUMSAccount, UMSTAG_CfgUser, unode->UserData.RealName,
  2016.                                          UMSTAG_CfgCreateAlias, unode->UserData.Name,
  2017.                                          TAG_DONE))
  2018.       if (WriteUMSConfigTags(SysUMSAccount, UMSTAG_CfgUser, unode->UserData.RealName,
  2019.                                             UMSTAG_CfgName, "READACCESS",
  2020.                                             UMSTAG_CfgData, "#?",
  2021.                                             TAG_DONE))
  2022.          if (WriteUMSConfigTags(SysUMSAccount, UMSTAG_CfgUser, unode->UserData.RealName,
  2023.                                                UMSTAG_CfgName, "WRITEACCESS",
  2024.                                                UMSTAG_CfgData, "#?",
  2025.                                                TAG_DONE))
  2026.             if (WriteUMSConfigTags(SysUMSAccount, UMSTAG_CfgUser, unode->UserData.RealName,
  2027.                                                   UMSTAG_CfgName, "NETACCESS",
  2028.                                                   UMSTAG_CfgData, "#?",
  2029.                                                   TAG_DONE))
  2030.                return TRUE;
  2031.  
  2032.    WriteUMSConfigTags(SysUMSAccount, UMSTAG_CfgDeleteUser, unode->UserData.RealName,
  2033.                                      TAG_DONE);
  2034.  
  2035.    return FALSE;
  2036.    }
  2037.  
  2038. ///
  2039.  
  2040. /********************************
  2041.  * UMS-Usereintrag löschen      *
  2042.  ********************************
  2043.  * I: struct UserNode *         *
  2044.  * O: Erfolg TRUE/FALSE         *
  2045.  ********************************/
  2046.  
  2047. /// DelUMSUser
  2048.  
  2049. BOOL DelUMSUser(struct UserNode *unode)
  2050.    {
  2051.    if (!WriteUMSConfigTags(SysUMSAccount, UMSTAG_CfgDeleteUser, unode->UserData.RealName,
  2052.                                           TAG_DONE))
  2053.       return FALSE;
  2054.    }
  2055.  
  2056. ///
  2057.  
  2058.